+2005-08-25 Øyvind Kolås <pippin@gimp.org>
+
+ * babl/babl-classes.h:
+ BablModel: added .type
+ BablFormat: reordered
+ BablImage: added .format, .model, .sampling and .type
+ BablFishReference: removed implementation details
+ * babl/babl-component.c: (component_new): use malloc instead of calloc
+ * babl/babl-conversion.c:
+ (conversion_new): use malloc instead of calloc
+ (babl_conversion_linear_process)
+ (babl_conversion_process): pass pitch to functions.
+ (babl_conversion_planar_process): duplicate data pointers in
+ image before passing them on.
+ * babl/babl-db.h:
+ (db_each): indentation fix.
+ * babl/babl-fish.c:
+ (babl_fish_reference_new),
+ (babl_fish_reference_process),
+ (babl_fish_process), (babl_process): restructuring of the
+ reference bablfish, approaching data and component shuffling
+ functionality.
+ * babl/babl-image.c:
+ (image_new): use malloc instead of calloc
+ (babl_image_from_linear), (babl_image): Added more information
+ to structure.
+ * babl/babl-image.h: s/_new//
+ * babl/babl-internal.h: #define BABL_MAX_COMPONENTS 32
+ * babl/babl-introspect.c:
+ (format_introspect): s/bands/components/
+ * babl/babl-model.c:
+ (model_new): use malloc instead of calloc
+ * babl/babl-pixel-format.c:
+ (format_new): use malloc instead of calloc
+ (babl_format_new): s/bands/components/
+ * babl/babl-type.c:
+ (type_new): use malloc instead of calloc
+
+
+ * babl/base/type-double.c,
+ * babl/base/type-float.c,
+ * babl/base/type-u16.c,
+ * babl/base/type-u8.c: more parameters to conversion functions, added
+ a codewriting macro for different scale / min/max factors.
+
+ * docs/index-static.html.in: reindent.
+ * tests/babl-html-dump.c: (format_html): s/bands/components/
+ * tests/srgb_to_lab_u8.c: (test): use absolute error in check.
+
2005-08-24 Øyvind Kolås <pippin@gimp.org>
* tests/sanity.c: Added a test that fails if the internal sanity
/* Type and Format */
typedef void (*BablFuncLinear) (void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n);
/* TypePlanar, ModelPlanar and FormatPlanar */
BablConversion **to; /*< NULL terminated list of conversions to class */
int components;
BablComponent **component;
+ BablType **type; /*< must be doubles, used here for convenience in code */
} BablModel;
typedef struct
BablInstance instance;
BablConversion **from; /*< NULL terminated list of conversions from class */
BablConversion **to; /*< NULL terminated list of conversions to class */
- int bands;
- int planar;
- BablModel *model;
+ int components;
BablComponent **component;
BablType **type;
BablSampling **sampling;
+ BablModel *model;
+ int planar;
} BablFormat;
typedef struct
{
BablInstance instance;
+ BablFormat *format; /*< (if known) */
+ BablModel *model; /*< (always known) */
int bands;
BablComponent **component;
+ BablSampling **sampling;
+ BablType **type;
void **data;
int *pitch;
int *stride;
} BablFish;
-/* a BablFish which is a reference babl fish relies on the double
- * versions that are required to exist for maximum sanity.
+/* BablFishReference on the double versions of conversions
+ * that are required to exist for maximum sanity.
*
* A BablFishReference is not intended to be fast, thus the algorithm
* encoded can use a multi stage approach, where some of the stages could
*
* One of the contributions that would be welcome are new fish factories.
*/
-
-
typedef struct
{
BablFish fish;
-
- BablConversion *type_to_double;
- BablConversion *model_to_rgba;
- BablConversion *rgba_to_model;
- BablConversion *double_to_type;
} BablFishReference;
typedef union
{
Babl *babl;
- babl = babl_calloc (sizeof (BablComponent) +
- strlen (name) + 1, 1);
+ babl = babl_malloc (sizeof (BablComponent) + strlen (name) + 1);
babl->instance.name = (void *) babl + sizeof (BablComponent);
strcpy (babl->instance.name, name);
babl->component.luma = luma;
babl->component.chroma = chroma;
babl->component.alpha = alpha;
-
+ babl->component.from = NULL;
+ babl->component.to = NULL;
return babl;
}
case BABL_TYPE:
if (linear)
{
- babl = babl_calloc (sizeof (BablConversionType), 1);
+ babl = babl_malloc (sizeof (BablConversionType));
babl->class_type = BABL_CONVERSION_TYPE;
babl->conversion.function.linear = linear;
}
else if (planar)
{
- babl = babl_calloc (sizeof (BablConversionTypePlanar), 1);
+ babl = babl_malloc (sizeof (BablConversionTypePlanar));
babl->class_type = BABL_CONVERSION_TYPE_PLANAR;
babl->conversion.function.planar = planar;
}
}
else if (planar)
{
- babl = babl_calloc (sizeof (BablConversionModelPlanar), 1);
+ babl = babl_malloc (sizeof (BablConversionModelPlanar));
babl->class_type = BABL_CONVERSION_MODEL_PLANAR;
babl->conversion.function.planar = planar;
}
case BABL_FORMAT:
if (linear)
{
- babl = babl_calloc (sizeof (BablConversionFormat), 1);
+ babl = babl_malloc (sizeof (BablConversionFormat));
babl->class_type = BABL_CONVERSION_FORMAT;
babl->conversion.function.linear = linear;
}
else if (planar)
{
- babl = babl_calloc (sizeof (BablConversionFormatPlanar), 1);
+ babl = babl_malloc (sizeof (BablConversionFormatPlanar));
babl->class_type = BABL_CONVERSION_FORMAT_PLANAR;
babl->conversion.function.planar = planar;
}
babl_conversion_linear_process (BablConversion *conversion,
void *source,
void *destination,
+ int src_pitch,
+ int dst_pitch,
long n)
{
- conversion->function.linear (source, destination, n);
+ conversion->function.linear (source, destination, src_pitch, dst_pitch, n);
}
static void
BablImage *destination,
long n)
{
+#ifdef USE_ALLOCA
+ void **src_data = alloca (sizeof (void*) * source->bands);
+ void **dst_data = alloca (sizeof (void*) * destination->bands);
+#else
+ void *src_data[BABL_MAX_COMPONENTS];
+ void *dst_data[BABL_MAX_COMPONENTS];
+#endif
+
+ memcpy (src_data, source->data, sizeof (void*) * source->bands);
+ memcpy (dst_data, destination->data, sizeof (void*) * destination->bands);
+
conversion->function.planar (source->bands,
- source->data,
+ src_data,
source->pitch,
destination->bands,
- destination->data,
+ dst_data,
destination->pitch,
n);
}
switch (BABL(conversion)->class_type)
{
case BABL_CONVERSION_TYPE:
- babl_conversion_linear_process (conversion,
- source,
- destination,
- n);
+ {
+ void *src_data = NULL;
+ void *dst_data = NULL;
+ int src_pitch = 0;
+ int dst_pitch = 0;
+
+ if (BABL_IS_BABL(source))
+ {
+ BablImage *img;
+
+ img = (BablImage*)source;
+ src_data = img->data[0];
+ src_pitch = img->pitch[0];
+ }
+ if (!src_data)
+ src_data=source;
+ if (!src_pitch)
+ src_pitch=BABL(conversion->source)->type.bits/8;
+
+
+ if (BABL_IS_BABL(destination))
+ {
+ BablImage *img;
+
+ img = (BablImage*)destination;
+ dst_data = img->data[0];
+ dst_pitch = img->pitch[0];
+ }
+ if (!dst_data)
+ dst_data=destination;
+ if (!dst_pitch)
+ dst_pitch=BABL(conversion->destination)->type.bits/8;
+
+ babl_conversion_linear_process (conversion,
+ src_data, dst_data,
+ src_pitch, dst_pitch,
+ n);
+ }
break;
case BABL_CONVERSION_MODEL_PLANAR:
assert (BABL_IS_BABL (source));
DB_DEF void
db_each (BablEachFunction each_fun,
- void *user_data)
+ void *user_data)
{
int i;
assert (BABL_IS_BABL (source));
assert (BABL_IS_BABL (destination));
- assert (source->class_type == BABL_FORMAT ||
- source->class_type == BABL_MODEL);
- assert (destination->class_type == BABL_FORMAT ||
- destination->class_type == BABL_MODEL);
+ assert (source->class_type == BABL_FORMAT);
+ assert (destination->class_type == BABL_FORMAT);
babl = babl_calloc (sizeof (BablFishReference), 1);
babl->class_type = BABL_FISH_REFERENCE;
babl->fish.source = (union Babl*)source;
babl->fish.destination = (union Babl*)destination;
- if (source->class_type == BABL_FORMAT)
- {
- babl->reference_fish.type_to_double =
- babl_conversion_find (
- source->format.type[0],
- babl_type_id (BABL_DOUBLE)
- );
-
- babl->reference_fish.model_to_rgba =
- babl_conversion_find (
- source->format.model,
- babl_model_id (BABL_RGBA)
- );
-
- babl->reference_fish.rgba_to_model =
- babl_conversion_find (
- babl_model_id (BABL_RGBA),
- destination->format.model
- );
-
- babl->reference_fish.double_to_type =
- babl_conversion_find (
- babl_type_id (BABL_DOUBLE),
- destination->format.type[0]
- );
- }
- else if (source->class_type == BABL_MODEL)
- {
- babl->reference_fish.type_to_double = NULL;
-
- babl_log ("EEEEEEEEEEEEEEEEEEEEK!%s","!!!!");
-
- babl->reference_fish.model_to_rgba =
- babl_conversion_find (
- source->format.model,
- babl_model_id (BABL_RGBA)
- );
-
- babl->reference_fish.rgba_to_model =
- babl_conversion_find (
- babl_model_id (BABL_RGBA),
- destination->format.model
- );
-
- babl->reference_fish.double_to_type =
- babl_conversion_find (
- babl_type_id (BABL_DOUBLE),
- destination->format.type[0]
- );
- }
-
if (db_insert (babl) == babl)
{
return babl;
return NULL;
}
-/* Might make sense to allow a precalculated shortcut to
- * participate in later checks for optimal conversions, then we
- * should also have better generated names,. model + datatype
- * is a possibility , or even full single line serialization of
- * components with types.
-
- babl_add_ptr_to_list ((void ***)&(source->type.from), babl);
- babl_add_ptr_to_list ((void ***)&(destination->type.to), babl);
- */
return babl;
}
return babl_fish_reference_new (source_format, destination_format);
}
-void *fooA;
-void *fooB;
-void *fooC;
-
-#define BABL_MAX_BANDS 32
-
-/* should perhaps have been babl_fish_process, but the public api
- * is shorther and makes sense for the API
- */
-int
-babl_process (Babl *babl,
- void *source,
- void *destination,
- int n)
+static int
+babl_fish_reference_process (Babl *babl,
+ BablImage *source,
+ BablImage *destination,
+ long n)
{
- Babl *imageA;
- Babl *imageB;
- Babl *imageC;
+ void *source_double_buf;
+ void *rgba_double_buf;
+ void *destination_double_buf;
+ Babl *source_image;
+ Babl *rgba_image;
+ Babl *destination_image;
/* FIXME: assumptions made about memory requirements that
* are not good
*/
- fooA = babl_malloc(sizeof (double) * n * 4);
- fooB = babl_malloc(sizeof (double) * n * 4);
-
- assert (babl);
- assert (source);
- assert (destination);
- assert (babl->class_type == BABL_FISH ||
- babl->class_type == BABL_FISH_REFERENCE);
+ source_double_buf = babl_malloc(sizeof (double) * n * 4);
+ rgba_double_buf = babl_malloc(sizeof (double) * n * 4);
+ destination_double_buf = babl_malloc(sizeof (double) * n * 4);
+
+ source_image = babl_image_from_linear (
+ source_double_buf,
+ BABL(BABL((babl->fish.source)) -> format.model));
+ rgba_image = babl_image_from_linear (
+ rgba_double_buf,
+ babl_model_id (BABL_RGBA));
+ destination_image = babl_image_from_linear (
+ destination_double_buf,
+ BABL(BABL((babl->fish.destination))->format.model));
if (BABL_IS_BABL (source) ||
BABL_IS_BABL (destination))
{
- babl_log ("%s(%p, %p, %p, %i): not handling BablImage yet",
+ babl_log ("%s(%p, %p, %p, %li): not handling BablImage yet",
__FUNCTION__, babl_fish, source, destination, n);
return -1;
}
-
- babl_conversion_process (babl->reference_fish.type_to_double,
- source, fooA,
- n * BABL(babl->fish.source)->format.bands);
-
- /* calculate planar representation of fooA, and fooB */
-
- imageA = babl_image_new_from_linear (fooA, BABL(BABL((babl->fish.source)) -> format.model));
- imageB = babl_image_new_from_linear (fooB, babl_model_id (BABL_RGBA));
- /* transform fooA into fooB fooB is rgba double */
-
- babl_conversion_process (babl->reference_fish.model_to_rgba,
- imageA, imageB,
- n);
-
- babl_free (imageA);
- babl_free (imageB);
- /* calculate planar representation of fooC */
- /* transform fooB into fooC fooC is ???? double */
+#if 0 /* draft code*/
+ {
+ int i;
+ BablFormat *source_fmt = (BablFormat*)BABL(babl->fish.source);
+ BablFormat *destination_fmt = (BablFormat*)BABL(babl->fish.destination);
+
+ BablImage *src_img = babl_image ("R", pr, 1, 0, NULL);
+ BablImage *dst_img = babl_image ("R", pr, 1, 0, NULL);
+
+ for (i=0 ; i< destination_fmt->components; i++)
+ {
+ int j;
+
+ dst_img->type[0] = destination_fmt->type[i];
+ dst_img->pitch[0] = destination_fmt->pitch[i];
+ dst_img->stride[0] = destination_fmt->stride[i];
+ dst_img->data[0] = destination_fmt->data[i];
+
+ for (j=0;j<source_fmt->components;j++)
+ {
+ if (source_fmt->component[j] == destination_fmt[i])
+ {
+ src_img->type[0] = source_fmt->type[j];
+ src_img->pitch[0] = source_fmt->pitch[j];
+ src_img->stride[0] = source_fmt->stride[j];
+ src_img->data[0] = source_fmt->data[j];
+ break;
+ }
+ babl_log ("%s(): matching source component not found", __FUNCTION);
+ }
+
+ babl_conversion_process (
+ babl_conversion_find (
+ src_img->type[0],
+ dst_img->type[0]
+ /*babl_type_id (BABL_DOUBLE)*/
+ ),
+ source, source_double_buf,
+ n);
+ }
+ }
+#endif
+#if 1
+ babl_conversion_process (
+ babl_conversion_find (
+ BABL(babl->fish.source)->format.type[0],
+ babl_type_id (BABL_DOUBLE)
+ ),
+ source, source_double_buf,
+ n * BABL(babl->fish.source)->format.components);
+#endif
+
+ /* calculate planar representation of source_double, and rgba_double_buf */
+ /* transform source_double_buf into rgba_double_buf rgba_double_buf is rgba double */
+
+ babl_conversion_process (
+ babl_conversion_find (
+ BABL(babl->fish.source)->format.model,
+ babl_model_id (BABL_RGBA)
+ ),
+ source_image, rgba_image,
+ n);
+
+ /* calculate planar representation of destination_double_buf */
+ /* transform rgba_double_buf into destination_double_buf destination_double_buf is ???? double */
+
+ babl_conversion_process (
+ babl_conversion_find (
+ babl_model_id (BABL_RGBA),
+ BABL(babl->fish.destination)->format.model
+ ),
+ rgba_image, destination_image,
+ n);
+
+ /* FIXME: working directly on linear buffers */
+ babl_conversion_process (
+ babl_conversion_find (
+ babl_type_id (BABL_DOUBLE),
+ BABL(babl->fish.destination)->format.type[0]
+ ),
+ destination_double_buf, destination,
+ n * BABL(babl->fish.destination)->format.components);
+
+ babl_free (source_image);
+ babl_free (rgba_image);
+ babl_free (destination_image);
+
+ babl_free (destination_double_buf);
+ babl_free (rgba_double_buf);
+ babl_free (source_double_buf);
+ return 0;
+}
- imageB = babl_image_new_from_linear (
- fooB, babl_model_id (BABL_RGBA));
- imageC = babl_image_new_from_linear (
- fooA, BABL(BABL((babl->fish.destination))->format.model));
+static int
+babl_fish_process (Babl *babl,
+ void *source,
+ void *destination,
+ long n)
+{
+ babl_log ("%s(): NYI", __FUNCTION__);
+ return -1;
+}
- babl_conversion_process (babl->reference_fish.rgba_to_model,
- imageB, imageC,
- n);
- /* working directly on linear buffers */
- babl_conversion_process (babl->reference_fish.double_to_type,
- fooA, destination,
- n * BABL(babl->fish.destination)->format.bands);
+int
+babl_process (Babl *babl,
+ void *source,
+ void *destination,
+ long n)
+{
+ assert (babl);
+ assert (source);
+ assert (destination);
+ assert (BABL_IS_BABL (babl));
+ assert (n>0);
- babl_free (imageB);
- babl_free (imageC);
+ if (babl->class_type == BABL_FISH)
+ return babl_fish_process (babl, source, destination, n);
+
+ if (babl->class_type == BABL_FISH_REFERENCE)
+ {
+ BablImage *source_image = NULL;
+ BablImage *destination_image = NULL;
+
+ if (BABL_IS_BABL (source))
+ source_image = source;
+ if (!source_image)
+ source_image = (BablImage*) babl_image_from_linear (
+ source, (Babl*)babl->fish.source);
+ if (BABL_IS_BABL (destination))
+ destination_image = destination;
+ if (!destination_image)
+ destination_image = (BablImage*) babl_image_from_linear (
+ destination, (Babl*)babl->fish.destination);
+
+ babl_fish_reference_process (babl, source, destination, n);
+
+ babl_free (source_image);
+ babl_free (destination_image);
+
+ return 0;
+ }
- babl_free (fooA);
- babl_free (fooB);
- return 0;
+ babl_log ("%s(): eek", __FUNCTION__);
+ return -1;
}
BABL_DEFINE_INIT (babl_fish)
#include "babl-component.h"
#include "babl-db.h"
-#define BABL_MAX_BANDS 32
-
static int
each_babl_format_destroy (Babl *babl,
void *data)
format_new (const char *name,
int id,
int planar,
- int bands,
+ int components,
BablModel *model,
BablComponent **component,
BablSampling **sampling,
BablType **type)
{
Babl *babl;
- int band;
/* allocate all memory in one chunk */
- babl = babl_calloc (sizeof (BablFormat) +
+ babl = babl_malloc (sizeof (BablFormat) +
strlen (name) + 1 +
- sizeof (BablComponent*) * (bands+1) +
- sizeof (BablSampling*) * (bands+1) +
- sizeof (BablType*) * (bands+1) +
- sizeof (int) * (bands+1) +
- sizeof (int) * (bands+1),1);
+ sizeof (BablComponent*) * (components) +
+ sizeof (BablSampling*) * (components) +
+ sizeof (BablType*) * (components) +
+ sizeof (int) * (components) +
+ sizeof (int) * (components));
babl->format.component = ((void *)babl) + sizeof (BablFormat);
- babl->format.type = ((void *)babl->format.component) + sizeof (BablComponent*) * (bands+1);
- babl->format.sampling = ((void *)babl->format.type) + sizeof (BablType*) * (bands+1);
- babl->instance.name = ((void *)babl->format.sampling) + sizeof (BablSampling*) * (bands+1);
+ babl->format.type = ((void *)babl->format.component) + sizeof (BablComponent*) * (components);
+ babl->format.sampling = ((void *)babl->format.type) + sizeof (BablType*) * (components);
+ babl->instance.name = ((void *)babl->format.sampling) + sizeof (BablSampling*) * (components);
babl->class_type = BABL_FORMAT;
babl->instance.id = id;
+
strcpy (babl->instance.name, name);
+ babl->format.model = model;
+ babl->format.components = components;
+ babl->format.planar = planar;
- babl->format.model = model;
- babl->format.bands = bands;
- babl->format.planar = planar;
+ memcpy (babl->format.component, component, sizeof (BablComponent*) * components);
+ memcpy (babl->format.type , type , sizeof (BablType*) * components);
+ memcpy (babl->format.sampling , sampling , sizeof (BablSampling*) * components);
- for (band=0; band < bands; band++)
- {
- babl->format.component[band] = component[band];
- babl->format.type[band] = type[band];
- babl->format.sampling[band] = sampling[band];
- }
- babl->format.component[band] = NULL;
- babl->format.type[band] = NULL;
- babl->format.sampling[band] = NULL;
+ babl->format.from = NULL;
+ babl->format.to = NULL;
return babl;
}
Babl *babl;
int id = 0;
int planar = 0;
- int bands = 0;
+ int components = 0;
BablModel *model = NULL;
- BablComponent *component [BABL_MAX_BANDS];
- BablSampling *sampling [BABL_MAX_BANDS];
- BablType *type [BABL_MAX_BANDS];
+ BablComponent *component [BABL_MAX_COMPONENTS];
+ BablSampling *sampling [BABL_MAX_COMPONENTS];
+ BablType *type [BABL_MAX_COMPONENTS];
BablSampling *current_sampling = (BablSampling*) babl_sampling (1,1);
BablType *current_type = (BablType*) babl_type_id (BABL_U8);
babl_log ("%s(): no model specified before component %s",
__FUNCTION__, babl->instance.name);
}
- component [bands] = (BablComponent*) babl;
- type [bands] = current_type;
- sampling [bands] = current_sampling;
- bands++;
+ component [components] = (BablComponent*) babl;
+ type [components] = current_type;
+ sampling [components] = current_sampling;
+ components++;
- if (bands>=BABL_MAX_BANDS)
+ if (components>=BABL_MAX_COMPONENTS)
{
- babl_log ("%s(): maximum number of bands (%i) exceeded for %s",
- __FUNCTION__, BABL_MAX_BANDS, name);
+ babl_log ("%s(): maximum number of components (%i) exceeded for %s",
+ __FUNCTION__, BABL_MAX_COMPONENTS, name);
}
break;
case BABL_SAMPLING:
babl = format_new (name, id,
- planar, bands, model,
+ planar, components, model,
component, sampling, type);
#include "babl-internal.h"
#include "babl-image.h"
#include "babl-type.h"
+#include "babl-sampling.h"
#include "babl-component.h"
-#define BABL_MAX_BANDS 32
static Babl *
-image_new (int bands,
+image_new (BablFormat *format,
+ BablModel *model,
+ int bands,
BablComponent **component,
+ BablSampling **sampling,
+ BablType **type,
void **data,
int *pitch,
int *stride)
{
Babl *babl;
- int band;
/* allocate all memory in one chunk */
- babl = babl_calloc (sizeof (BablImage) +
- sizeof (BablComponent*) * (bands+1) +
- sizeof (void*) * (bands+1) +
- sizeof (int) * (bands+1) +
- sizeof (int) * (bands+1),1);
+ babl = babl_malloc (sizeof (BablImage) +
+ sizeof (BablComponent*) * (bands) +
+ sizeof (BablSampling*) * (bands) +
+ sizeof (BablType*) * (bands) +
+ sizeof (void*) * (bands) +
+ sizeof (int) * (bands) +
+ sizeof (int) * (bands));
babl->image.component = ((void *)babl) + sizeof (BablImage);
- babl->image.data = ((void *)babl->image.component) + sizeof (BablComponent*) * (bands+1);
- babl->image.pitch = ((void *)babl->image.data) + sizeof (void*) * (bands+1);
- babl->image.stride = ((void *)babl->image.pitch) + sizeof (int) * (bands+1);
+ babl->image.sampling = ((void *)babl->image.component) + sizeof (BablComponent*) * (bands);
+ babl->image.type = ((void *)babl->image.sampling) + sizeof (BablSampling*) * (bands);
+ babl->image.data = ((void *)babl->image.type) + sizeof (BablType*) * (bands);
+ babl->image.pitch = ((void *)babl->image.data) + sizeof (void*) * (bands);
+ babl->image.stride = ((void *)babl->image.pitch) + sizeof (int) * (bands);
babl->class_type = BABL_IMAGE;
babl->instance.id = 0;
- babl->instance.name = "babl image";
+ babl->instance.name = "slaritbartfast";
+ babl->image.format = format;
+ babl->image.model = model;
babl->image.bands = bands;
-
- for (band=0; band < bands; band++)
- {
- babl->image.component[band] = component[band];
- babl->image.data[band] = data[band];
- babl->image.pitch[band] = pitch[band];
- babl->image.stride[band] = stride[band];
- }
- babl->image.component[band] = NULL;
- babl->image.data[band] = NULL;
- babl->image.pitch[band] = 0;
- babl->image.stride[band] = 0;
+ memcpy (babl->image.component, component, bands * sizeof(void*));
+ memcpy (babl->image.type, type, bands * sizeof(void*));
+ memcpy (babl->image.data, data, bands * sizeof(void*));
+ memcpy (babl->image.pitch, pitch, bands * sizeof(int));
+ memcpy (babl->image.stride, stride, bands * sizeof(int));
return babl;
}
Babl *
-babl_image_new_from_linear (void *buffer,
+babl_image_from_linear (void *buffer,
Babl *format)
{
Babl *babl;
- int band;
- BablComponent *component [BABL_MAX_BANDS];
- void *data [BABL_MAX_BANDS];
- int pitch [BABL_MAX_BANDS];
- int stride [BABL_MAX_BANDS];
+ BablModel *model;
+ int components;
+ int i;
+ BablComponent *component [BABL_MAX_COMPONENTS];
+ BablSampling *sampling [BABL_MAX_COMPONENTS];
+ BablType *type [BABL_MAX_COMPONENTS];
+ void *data [BABL_MAX_COMPONENTS];
+ int pitch [BABL_MAX_COMPONENTS];
+ int stride [BABL_MAX_COMPONENTS];
int offset=0;
int calc_pitch=0;
switch (format->class_type)
{
case BABL_FORMAT:
- for (band=0; band < format->format.bands; band++)
+ model = (BablModel*) format->format.model;
+ components = format->format.components;
+
+ memcpy(component, format->format.component, sizeof (Babl*) * components);
+ memcpy(sampling, format->format.sampling, sizeof (Babl*) * components);
+ memcpy(type , format->format.type, sizeof (Babl*) * components);
+
+ for (i=0; i < components; i++)
{
- BablType *type = format->format.type[band];
- calc_pitch += (type->bits / 8);
+ calc_pitch += (type[i]->bits / 8);
}
-
- for (band=0; band < format->format.bands; band++)
+ for (i=0; i < components; i++)
{
- BablType *type = format->format.type[band];
-
- component[band] = format->format.component[band];
- data[band] = buffer + offset;
- pitch[band] = calc_pitch;
- stride[band] = 0;
-
- offset += (type->bits / 8);
+ pitch[i] = calc_pitch;
+ stride[i] = 0;
+ data[i] = buffer + offset;
+ offset += (type[i]->bits / 8);
}
break;
case BABL_MODEL:
- for (band=0; band < format->model.components; band++)
+ model = (BablModel*) format;
+ components = format->format.components;
+ for (i=0; i < components; i++)
{
- calc_pitch += (64 / 8);
+ calc_pitch += (64 / 8); /*< known to be double when we create from model */
}
-
- for (band=0; band < format->model.components; band++)
+ memcpy(component, model->component, sizeof (Babl*) * components);
+ for (i=0; i < components; i++)
{
- component[band] = format->model.component[band];
- data[band] = buffer + offset;
- pitch[band] = calc_pitch;
- stride[band] = 0;
-
- offset += (64 / 8);
+ sampling[i] = (BablSampling*)babl_sampling (1,1);
+ type[i] = (BablType*)babl_type_id (BABL_DOUBLE);
+ pitch[i] = calc_pitch;
+ stride[i] = 0;
+ data[i] = buffer + offset;
+ offset += (type[i]->bits / 8);
}
break;
default:
+ babl_log ("%s(): Eeeek!", __FUNCTION__);
break;
}
- babl = image_new (format->model.components, component, data, pitch, stride);
+ babl = image_new (
+ (BablFormat*)format,
+ model, components,
+ component, sampling, type, data, pitch, stride);
return babl;
}
Babl *
-babl_image_new (void *first,
- ...)
+babl_image (void *first,
+ ...)
{
va_list varg;
Babl *babl;
- int bands = 0;
- BablComponent *component [BABL_MAX_BANDS];
- void *data [BABL_MAX_BANDS];
- int pitch [BABL_MAX_BANDS];
- int stride [BABL_MAX_BANDS];
+ int components = 0;
+ BablFormat *format = NULL;
+ BablModel *model = NULL;
+ BablComponent *component [BABL_MAX_COMPONENTS];
+ BablSampling *sampling [BABL_MAX_COMPONENTS];
+ BablType *type [BABL_MAX_COMPONENTS];
+ void *data [BABL_MAX_COMPONENTS];
+ int pitch [BABL_MAX_COMPONENTS];
+ int stride [BABL_MAX_COMPONENTS];
const char *arg = first;
}
/* FIXME: add error checking */
- component [bands] = new_component;
- data [bands] = va_arg (varg, void*);
- pitch [bands] = va_arg (varg, int);
- stride [bands] = va_arg (varg, int);
- bands++;
+ component [components] = new_component;
+ sampling [components] = NULL;
+ type [components] = NULL;
+ data [components] = va_arg (varg, void*);
+ pitch [components] = va_arg (varg, int);
+ stride [components] = va_arg (varg, int);
+ components++;
- if (bands>=BABL_MAX_BANDS)
+ if (components>=BABL_MAX_COMPONENTS)
{
- babl_log ("%s(): maximum number of bands (%i) exceeded",
- __FUNCTION__, BABL_MAX_BANDS);
+ babl_log ("%s(): maximum number of components (%i) exceeded",
+ __FUNCTION__, BABL_MAX_COMPONENTS);
}
arg = va_arg (varg, char *);
va_end (varg);
- babl = image_new (bands, component, data, pitch, stride);
-
+ babl = image_new (format, model, components, component, sampling, type, data, pitch, stride);
return babl;
}
* is a virtual pixelformat based on the BablModel using only doubles in the
* order they are listed in the model.
*/
-Babl * babl_image_new_from_linear (void *buffer,
- Babl *format);
+Babl * babl_image_from_linear (void *buffer,
+ Babl *format);
+
+/* create a new babl image similar to the provided babl-image, but where all data
+ * is in doubles,..
+ */
+Babl * babl_image_double_from_image (Babl *source);
#endif
#ifndef _BABL_INTERNAL_H
#define _BABL_INTERNAL_H
+#define BABL_MAX_COMPONENTS 32
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
{
int i;
babl_log ("\t\tplanar=%i", babl->format.planar);
- babl_log ("\t\tbands=%i", babl->format.bands);
+ babl_log ("\t\tcomponents=%i", babl->format.components);
- for (i=0; i< babl->format.bands; i++)
+ for (i=0; i< babl->format.components; i++)
{
babl_log ("\t\tband[%i] type='%s' component='%s' sampling='%s'",
i, babl->format.type[i]->instance.name,
return 0; /* continue iterating */
}
-
-#define BABL_MAX_COMPONENTS 32
-
static Babl *
model_new (const char *name,
int id,
BablComponent **component)
{
Babl *babl;
- int i;
- babl = babl_calloc (sizeof (BablModel) +
- sizeof (BablComponent*) * (components+1) +
- strlen (name) + 1, 1);
+ babl = babl_malloc (sizeof (BablModel) +
+ sizeof (BablComponent*) * (components) +
+ strlen (name) + 1);
babl->model.component = ((void*)babl) + sizeof (BablModel);
- babl->instance.name = ((void*)babl->model.component) + sizeof (BablComponent*) * (components + 1);
+ babl->instance.name = ((void*)babl->model.component) + sizeof (BablComponent*) * (components);
babl->class_type = BABL_MODEL;
babl->instance.id = id;
babl->model.components = components;
strcpy (babl->instance.name, name);
+ memcpy (babl->model.component, component, sizeof (BablComponent*)*components);
- for (i=0; i < components; i++)
- {
- babl->model.component[i] = component[i];
- }
- babl->model.component[i] = NULL;
-
+ babl->model.from = NULL;
+ babl->model.to = NULL;
return babl;
}
Babl *babl;
int id = 0;
int components = 0;
- BablComponent *band_component [BABL_MAX_COMPONENTS];
+ BablComponent *component [BABL_MAX_COMPONENTS];
const char *arg=name;
va_start (varg, name);
switch (babl->class_type)
{
case BABL_COMPONENT:
- band_component [components] = (BablComponent*) babl;
+ component [components] = (BablComponent*) babl;
components++;
if (components>=BABL_MAX_COMPONENTS)
va_end (varg);
- babl = model_new (name, id, components, band_component);
+ babl = model_new (name, id, components, component);
if (db_insert (babl) == babl)
{
#include "babl-component.h"
#include "babl-db.h"
-#define BABL_MAX_BANDS 32
-
static int
each_babl_format_destroy (Babl *babl,
void *data)
format_new (const char *name,
int id,
int planar,
- int bands,
+ int components,
BablModel *model,
BablComponent **component,
BablSampling **sampling,
BablType **type)
{
Babl *babl;
- int band;
/* allocate all memory in one chunk */
- babl = babl_calloc (sizeof (BablFormat) +
+ babl = babl_malloc (sizeof (BablFormat) +
strlen (name) + 1 +
- sizeof (BablComponent*) * (bands+1) +
- sizeof (BablSampling*) * (bands+1) +
- sizeof (BablType*) * (bands+1) +
- sizeof (int) * (bands+1) +
- sizeof (int) * (bands+1),1);
+ sizeof (BablComponent*) * (components) +
+ sizeof (BablSampling*) * (components) +
+ sizeof (BablType*) * (components) +
+ sizeof (int) * (components) +
+ sizeof (int) * (components));
babl->format.component = ((void *)babl) + sizeof (BablFormat);
- babl->format.type = ((void *)babl->format.component) + sizeof (BablComponent*) * (bands+1);
- babl->format.sampling = ((void *)babl->format.type) + sizeof (BablType*) * (bands+1);
- babl->instance.name = ((void *)babl->format.sampling) + sizeof (BablSampling*) * (bands+1);
+ babl->format.type = ((void *)babl->format.component) + sizeof (BablComponent*) * (components);
+ babl->format.sampling = ((void *)babl->format.type) + sizeof (BablType*) * (components);
+ babl->instance.name = ((void *)babl->format.sampling) + sizeof (BablSampling*) * (components);
babl->class_type = BABL_FORMAT;
babl->instance.id = id;
+
strcpy (babl->instance.name, name);
+ babl->format.model = model;
+ babl->format.components = components;
+ babl->format.planar = planar;
- babl->format.model = model;
- babl->format.bands = bands;
- babl->format.planar = planar;
+ memcpy (babl->format.component, component, sizeof (BablComponent*) * components);
+ memcpy (babl->format.type , type , sizeof (BablType*) * components);
+ memcpy (babl->format.sampling , sampling , sizeof (BablSampling*) * components);
- for (band=0; band < bands; band++)
- {
- babl->format.component[band] = component[band];
- babl->format.type[band] = type[band];
- babl->format.sampling[band] = sampling[band];
- }
- babl->format.component[band] = NULL;
- babl->format.type[band] = NULL;
- babl->format.sampling[band] = NULL;
+ babl->format.from = NULL;
+ babl->format.to = NULL;
return babl;
}
Babl *babl;
int id = 0;
int planar = 0;
- int bands = 0;
+ int components = 0;
BablModel *model = NULL;
- BablComponent *component [BABL_MAX_BANDS];
- BablSampling *sampling [BABL_MAX_BANDS];
- BablType *type [BABL_MAX_BANDS];
+ BablComponent *component [BABL_MAX_COMPONENTS];
+ BablSampling *sampling [BABL_MAX_COMPONENTS];
+ BablType *type [BABL_MAX_COMPONENTS];
BablSampling *current_sampling = (BablSampling*) babl_sampling (1,1);
BablType *current_type = (BablType*) babl_type_id (BABL_U8);
babl_log ("%s(): no model specified before component %s",
__FUNCTION__, babl->instance.name);
}
- component [bands] = (BablComponent*) babl;
- type [bands] = current_type;
- sampling [bands] = current_sampling;
- bands++;
+ component [components] = (BablComponent*) babl;
+ type [components] = current_type;
+ sampling [components] = current_sampling;
+ components++;
- if (bands>=BABL_MAX_BANDS)
+ if (components>=BABL_MAX_COMPONENTS)
{
- babl_log ("%s(): maximum number of bands (%i) exceeded for %s",
- __FUNCTION__, BABL_MAX_BANDS, name);
+ babl_log ("%s(): maximum number of components (%i) exceeded for %s",
+ __FUNCTION__, BABL_MAX_COMPONENTS, name);
}
break;
case BABL_SAMPLING:
babl = format_new (name, id,
- planar, bands, model,
+ planar, components, model,
component, sampling, type);
assert (bits != 0);
assert (bits % 8 == 0);
- babl = babl_calloc (sizeof (BablType) + strlen (name) + 1, 1);
+ babl = babl_malloc (sizeof (BablType) + strlen (name) + 1);
babl->instance.name = (void*) babl + sizeof (BablType);
babl->class_type = BABL_TYPE;
babl->instance.id = id;
strcpy (babl->instance.name, name);
babl->type.bits = bits;
+ babl->type.from = NULL;
+ babl->type.to = NULL;
return babl;
}
static void
convert_double_double (void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
- memcpy (dst, src, n/8);
+ if (src_pitch == 64 &&
+ dst_pitch == 64)
+ {
+ memcpy (dst, src, n/8);
+ return;
+ }
+ while (n--)
+ {
+ (*(double *) dst) = (*(double *) src);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
}
void
static void
convert_double_float (void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
{
(*(float *) dst) = (*(double *) src);
- dst += 4;
- src += 8;
+ dst += dst_pitch;
+ src += src_pitch;
}
}
static void
convert_float_double (void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
{
(*(double *) dst) = (*(float *) src);
- dst += 8;
- src += 4;
+ dst += dst_pitch;
+ src += src_pitch;
}
}
unsigned short max,
void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
u16val = (dval-min_val) / (max_val-min_val) * (max-min) + min;
*(unsigned short *) dst = u16val;
- dst += 2;
- src += 8;
+ dst += dst_pitch;
+ src += src_pitch;
}
}
unsigned short max,
void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
dval = (u16val-min) / (double)(max-min) * (max_val-min_val) + min_val;
(*(double *) dst) = dval;
- dst += 8;
- src += 1;
+ dst += dst_pitch;
+ src += src_pitch;
}
}
-
-
-static void
-convert_double_u16 (void *src,
- void *dst,
- int n)
-{
- while (n--)
- {
- double dval = *(double *) src;
- unsigned short u16val;
-
- if (dval < 0)
- u16val = 0;
- else if (dval > 1)
- u16val = 65535;
- else
- u16val = dval*65535.0;
- *(unsigned short *) dst = u16val;
- dst += 2;
- src += 8;
- }
-}
-
-static void
-convert_u16_double (void *src,
- void *dst,
- int n)
-{
- while (n--)
- {
- (*(double *) dst) = (*(unsigned short *) src / 65535.0);
- dst += 8;
- src += 2;
- }
+#define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
+static void \
+convert_##name##_double (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ int n) \
+{ \
+ convert_u16_double_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n);\
+} \
+static void \
+convert_double_##name (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ int n) \
+{ \
+ convert_double_u16_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n);\
}
+MAKE_CONVERSIONS(u16,0.0,1.0,0,0xffff);
/* source ICC.1:2004-10 */
-
-static void convert_double_u16_l (void *src, void *dst, int n){
- convert_double_u16_scaled (0.0, 100.0, 0x00, 0xffff, src, dst, n);
-}
-static void convert_u16_l_double (void *src, void *dst, int n){
- convert_u16_double_scaled (0.0, 100.0, 0x00, 0xffff, src, dst, n);
-}
-
-static void convert_double_u16_ab (void *src, void *dst, int n){
- convert_double_u16_scaled (-128.0, 127.0, 0x00, 0xffff, src, dst, n);
-}
-static void convert_u16_ab_double (void *src, void *dst, int n){
- convert_u16_double_scaled (-128.0, 127.0, 0x00, 0xffff, src, dst, n);
-}
-
+MAKE_CONVERSIONS (u16_l, 0.0, 100.0, 0x00, 0xffff);
+MAKE_CONVERSIONS (u16_ab, -128.0, 127.0, 0x00, 0xffff);
void
babl_base_type_u16 (void)
unsigned char max,
void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
u8val = (dval-min_val) / (max_val-min_val) * (max-min) + min;
*(unsigned char *) dst = u8val;
- dst += 1;
- src += 8;
+ src += src_pitch;
+ dst += dst_pitch;
}
}
unsigned char max,
void *src,
void *dst,
+ int src_pitch,
+ int dst_pitch,
int n)
{
while (n--)
dval = (u8val-min) / (double)(max-min) * (max_val-min_val) + min_val;
(*(double *) dst) = dval;
- dst += 8;
- src += 1;
- }
-}
-
-static void convert_u8_double (void *src, void *dst, int n){
- convert_u8_double_scaled (0.0, 1.0, 0, 255, src, dst, n);
-}
-static void convert_double_u8 (void *src, void *dst, int n){
- convert_double_u8_scaled (0.0, 1.0, 0, 255, src, dst, n);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
}
-static void convert_double_u8_luma (void *src, void *dst, int n){
- convert_double_u8_scaled (0.0, 1.0, 16, 235, src, dst, n);
-}
-static void convert_u8_luma_double (void *src, void *dst, int n){
- convert_u8_double_scaled (0.0, 1.0, 16, 235, src, dst, n);
+#define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
+static void \
+convert_##name##_double (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ int n) \
+{ \
+ convert_u8_double_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n); \
+} \
+static void \
+convert_double_##name (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ int n) \
+{ \
+ convert_double_u8_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n); \
}
-static void convert_double_u8_chroma (void *src, void *dst, int n){
- convert_double_u8_scaled (-0.5, 0.5, 16, 240, src, dst, n);
-}
-static void convert_u8_chroma_double (void *src, void *dst, int n){
- convert_u8_double_scaled (-0.5, 0.5, 16, 240, src, dst, n);
-}
+MAKE_CONVERSIONS (u8, 0.0, 1.0, 0x00, 0xff);
+MAKE_CONVERSIONS (u8_luma, 0.0, 1.0, 16, 235);
+MAKE_CONVERSIONS (u8_chroma, 0.0, 1.0, 16, 240);
/* source ICC.1:2004-10 */
-
-static void convert_double_u8_l (void *src, void *dst, int n){
- convert_double_u8_scaled (0.0, 100.0, 0x00, 0xff, src, dst, n);
-}
-static void convert_u8_l_double (void *src, void *dst, int n){
- convert_u8_double_scaled (0.0, 100.0, 0x00, 0xff, src, dst, n);
-}
-
-static void convert_double_u8_ab (void *src, void *dst, int n){
- convert_double_u8_scaled (-128.0, 127.0, 0x00, 0xff, src, dst, n);
-}
-static void convert_u8_ab_double (void *src, void *dst, int n){
- convert_u8_double_scaled (-128.0, 127.0, 0x00, 0xff, src, dst, n);
-}
-
+MAKE_CONVERSIONS (u8_l, 0.0, 100.0, 0x00, 0xff);
+MAKE_CONVERSIONS (u8_ab, -128.0, 127.0, 0x00, 0xff);
void
babl_base_type_u8 (void)
><span class='function'>babl_process</span> <span class='paren'>(</span><span class='function'>babl_fish</span> <span class='paren'>(</span><span class='string'>"srgb"</span>, <span class='string'>"y'cbcr420p"</span><span class='paren'>)</span>,
srgb_buffer,
<span class='function'>babl_image</span> <span class='paren'>(</span><span class='function'><span class='string'>"Y'"</span>, luma_buffer, 1, 0,
- <span class='string'>"Cb"</span>, cb_buffer, 1, 0,
- <span class='string'>"Cr"</span>, cr_buffer, 1, 0,
+ <span class='string'>"Cb"</span>, cb_buffer, 1, 0,
+ <span class='string'>"Cr"</span>, cr_buffer, 1, 0,
<span class='NULL'>NULL</span><span class='paren'>);</span>
</pre>
printf ("<td valign='top'>");
{
int bytes=0;
- for (i=0; i< babl->format.bands; i++)
+ for (i=0; i< babl->format.components; i++)
{
bytes += BABL(babl->format.type[i])->type.bits/8;
}
printf ("<span class='name'>%s</span>", BABL(babl->format.model)->instance.name );
printf ("</td>");
printf ("<td>");
- for (i=0; i< babl->format.bands; i++)
+ for (i=0; i< babl->format.components; i++)
{
printf ("<span class='type'>%s </span><span class='component'>%s</span><span class='spacer'> </span><br/>",
BABL(babl->format.type[i])->instance.name,
0.0, 0.0, 255};
unsigned char reference_buf [PIXELS*3]=
- { 0, 0, 0,
- 127, 0, 0,
- 255, 255, 255,
+ { 0, 128, 128,
+ 135, 128, 128,
+ 255, 128, 128,
0, 0, 0,
0, 0, 0,
0, 0, 0};
for (i=0; i<PIXELS * 3; i++)
{
- if ((destination_buf[i] - reference_buf[i]) > TOLERANCE)
+ if (abs(destination_buf[i] - reference_buf[i]) > TOLERANCE)
{
babl_log ("%2i (%2i%%3=%i, %2i/3=%i) is %i should be %i",
i, i,i%3, i,i/3, destination_buf[i], reference_buf[i]);